package cn.cjj.gulimall.member.service.impl;

import cn.cjj.gulimall.auth.vo.UserLoginVo;
import cn.cjj.gulimall.member.entity.MemberLevelEntity;
import cn.cjj.gulimall.member.exception.EmailExistException;
import cn.cjj.gulimall.member.exception.PhoneExistException;
import cn.cjj.gulimall.member.exception.UsernameExistException;
import cn.cjj.gulimall.member.service.MemberLevelService;
import cn.cjj.gulimall.member.vo.SocialUser;
import cn.cjj.gulimall.member.vo.UserRegisterVo;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ejlchina.http.HTTP;
import com.ejlchina.http.HttpResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import cn.cjj.common.utils.PageUtils;
import cn.cjj.common.utils.Query;

import cn.cjj.gulimall.member.dao.MemberDao;
import cn.cjj.gulimall.member.entity.MemberEntity;
import cn.cjj.gulimall.member.service.MemberService;


@Service("memberService")
public class MemberServiceImpl extends ServiceImpl<MemberDao, MemberEntity> implements MemberService {

    @Autowired
    MemberLevelService memberLevelService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<MemberEntity> page = this.page(
                new Query<MemberEntity>().getPage(params),
                new QueryWrapper<MemberEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public void register(UserRegisterVo user) {
        MemberEntity member = new MemberEntity();

        checkUsernameUnique(user.getUsername());
        checkPhoneUnique(user.getPhone());

        member.setUsername(user.getUsername());
        member.setMobile(user.getPhone());

        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
        member.setPassword(bCryptPasswordEncoder.encode(user.getPassword()));

        MemberLevelEntity memberLevel = memberLevelService.getDefaultLevel();
        member.setLevelId(memberLevel.getId());



        this.save(member);
    }

    @Override
    public void checkUsernameUnique(String username) throws UsernameExistException {
        if (isExist("username", username)) {
            throw new UsernameExistException();
        }
    }

    @Override
    public void checkEmailUnique(String email) throws EmailExistException {
        if (isExist("email", email)) {
            throw new EmailExistException();
        }
    }

    @Override
    public void checkPhoneUnique(String phone) throws PhoneExistException {
        if (isExist("mobile", phone)) {
            throw new PhoneExistException();
        }
    }

    @Override
    public MemberEntity login(UserLoginVo user) {
        String loginAccount = user.getLoginAccount();
        String password = user.getPassword();

        QueryWrapper<MemberEntity> wrapper = new QueryWrapper<MemberEntity>();
        wrapper.eq("username", loginAccount)
                .or().eq("mobile", loginAccount)
                .or().eq("email", loginAccount);

        MemberEntity member = this.getOne(wrapper);
        if (member == null) {
            return null;
        }

        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
        if (bCryptPasswordEncoder.matches(password, member.getPassword())) {
            return member;
        } else {
            return null;
        }
    }

    @Override
    public MemberEntity login(SocialUser user) {
        String uid = user.getUid();

        MemberEntity member = this.getOne(new QueryWrapper<MemberEntity>().eq("social_uid" , uid));
        if (member == null) {
            member = new MemberEntity();
            try {
                HTTP http = HTTP.builder()
                        .baseUrl("https://api.weibo.com")
                        .build();
                HttpResult httpResult = http.sync("/2/users/show.json")
                        .addUrlParam("access_token", user.getAccess_token())
                        .addUrlParam("uid", user.getUid())
                        .get();
                JSONObject jsonObject = httpResult.getBody().toJsonObject();
                String name = jsonObject.getString("name");
                member.setNickname(name);
                member.setUsername(name);
                String gender = jsonObject.getString("gender");
                member.setGender("m".equals(gender) ? 1 : 0);
            } catch (Exception e) {
                log.warn(e.getMessage());
            }

            member.setSocialUid(user.getUid());
            member.setAccessToken(user.getAccess_token());
            member.setExpiresIn(user.getExpires_in());

            this.save(member);

            return member;
        } else {
            MemberEntity updateMember = new MemberEntity();
            updateMember.setId(member.getId());
            updateMember.setAccessToken(user.getAccess_token());
            updateMember.setExpiresIn(user.getExpires_in());

            this.updateById(updateMember);

            member.setAccessToken(user.getAccess_token());
            member.setExpiresIn(user.getExpires_in());

            return member;
        }
    }


    public boolean isExist(String name, String value) {
        Integer count = baseMapper.selectCount(new QueryWrapper<MemberEntity>().eq(name, value).last("limit 1"));

        return count == 1;
    }
}